#pragma once

#include <assert.h>
#include <memory>
#include "OSType.h"
#include "EventEngine.h"
#include "EventFDTrigger.h"
using namespace std;

//
// CMessageDataV0: 无参的消息结构
//
template <typename TheClass>
class CMessageDataV0 : public CEventFDTrigger
{
public:
    CMessageDataV0(CEventEngine *pEngine, void (TheClass::*callback)(), TheClass *pThis)
        : CEventFDTrigger(pEngine)
    {
        m_callback = callback;
        m_pThis = pThis;
    }

    CMessageDataV0(CEventEngine *pEngine, void (TheClass::*callback)(), shared_ptr<TheClass> spThis)
        : CEventFDTrigger(pEngine)
    {
        assert(spThis != nullptr);
        m_callback = callback;
        m_spThis = spThis;
        m_pThis = spThis.get();
    }

private:
    virtual void OnEventFDTrigger() override { (m_pThis->*m_callback)(); delete this; }

private:
    TheClass*               m_pThis;
    shared_ptr<TheClass>    m_spThis;
    void (TheClass::*m_callback)();
};

//
// CMessageDataV1: 带1个模板参数的消息结构
//
template <typename TheClass, typename VarType1>
class CMessageDataV1 : public CEventFDTrigger
{
public:
    CMessageDataV1(CEventEngine *pEngine, void (TheClass::*callback)(VarType1 var1), VarType1 var1, TheClass *pThis)
        : CEventFDTrigger(pEngine), m_var1(var1)
    {
        m_callback = callback;
        m_pThis = pThis;
    }

    CMessageDataV1(CEventEngine *pEngine, void (TheClass::*callback)(VarType1 var1), VarType1 var1, shared_ptr<TheClass> spThis)
        : CEventFDTrigger(pEngine), m_var1(var1)
    {
        assert(spThis != nullptr);
        m_callback = callback;
        m_spThis = spThis;
        m_pThis = spThis.get();
    }

private:
    virtual void OnEventFDTrigger() override { (m_pThis->*m_callback)(m_var1); delete this; }

private:
    TheClass*               m_pThis;
    shared_ptr<TheClass>    m_spThis;
    void (TheClass::*m_callback)(VarType1 var1);
    VarType1                m_var1;
};

//
// CMessageDataV2: 带2个模板参数的消息结构
//
template <typename TheClass, typename VarType1, typename VarType2>
class CMessageDataV2 : public CEventFDTrigger
{
public:
    CMessageDataV2(CEventEngine *pEngine, void (TheClass::*callback)(VarType1 var1, VarType2 var2), VarType1 var1, VarType2 var2, TheClass *pThis)
        : CEventFDTrigger(pEngine), m_var1(var1), m_var2(var2)
    {
        m_callback = callback;
        m_pThis = pThis;
    }

    CMessageDataV2(CEventEngine *pEngine, void (TheClass::*callback)(VarType1 var1, VarType2 var2), VarType1 var1, VarType2 var2, shared_ptr<TheClass> spThis)
        : CEventFDTrigger(pEngine), m_var1(var1), m_var2(var2)
    {
        assert(spThis != nullptr);
        m_callback = callback;
        m_spThis = spThis;
        m_pThis = spThis.get();
    }

private:
    virtual void OnEventFDTrigger() override { (m_pThis->*m_callback)(m_var1, m_var2); delete this; }

private:
    TheClass*               m_pThis;
    shared_ptr<TheClass>    m_spThis;
    void (TheClass::*m_callback)(VarType1 var1, VarType2 var2);
    VarType1                m_var1;
    VarType2                m_var2;
};

//
// CMessageDataV3: 带3个模板参数的消息结构
//
template <typename TheClass, typename VarType1, typename VarType2, typename VarType3>
class CMessageDataV3 : public CEventFDTrigger
{
public:
    CMessageDataV3(CEventEngine *pEngine, void (TheClass::*callback)(VarType1 var1, VarType2 var2, VarType3 var3), VarType1 var1, VarType2 var2, VarType3 var3, TheClass *pThis)
        : CEventFDTrigger(pEngine), m_var1(var1), m_var2(var2), m_var3(var3)
    {
        m_callback = callback;
        m_pThis = pThis;
    }

    CMessageDataV3(CEventEngine *pEngine, void (TheClass::*callback)(VarType1 var1, VarType2 var2, VarType3 var3), VarType1 var1, VarType2 var2, VarType3 var3, shared_ptr<TheClass> spThis)
        : CEventFDTrigger(pEngine), m_var1(var1), m_var2(var2), m_var3(var3)
    {
        assert(spThis != nullptr);
        m_callback = callback;
        m_spThis = spThis;
        m_pThis = spThis.get();
    }

private:
    virtual void OnEventFDTrigger() override { (m_pThis->*m_callback)(m_var1, m_var2, m_var3); delete this; }

private:
    TheClass*               m_pThis;
    shared_ptr<TheClass>    m_spThis;
    void (TheClass::*m_callback)(VarType1 var1, VarType2 var2, VarType3 var3);
    VarType1                m_var1;
    VarType2                m_var2;
    VarType3                m_var3;
};

//
// CMessageDataV4: 带4个模板参数的消息结构
//
template <typename TheClass, typename VarType1, typename VarType2, typename VarType3, typename VarType4>
class CMessageDataV4 : public CEventFDTrigger
{
public:
    CMessageDataV4(CEventEngine *pEngine, void (TheClass::*callback)(VarType1 var1, VarType2 var2, VarType3 var3, VarType4 var4), VarType1 var1, VarType2 var2, VarType3 var3, VarType4 var4, TheClass *pThis)
        : CEventFDTrigger(pEngine), m_var1(var1), m_var2(var2), m_var3(var3), m_var4(var4)
    {
        m_callback = callback;
        m_pThis = pThis;
    }

    CMessageDataV4(CEventEngine *pEngine, void (TheClass::*callback)(VarType1 var1, VarType2 var2, VarType3 var3, VarType4 var4), VarType1 var1, VarType2 var2, VarType3 var3, VarType4 var4, shared_ptr<TheClass> spThis)
        : CEventFDTrigger(pEngine), m_var1(var1), m_var2(var2), m_var3(var3), m_var4(var4)
    {
        assert(spThis != nullptr);
        m_callback = callback;
        m_spThis = spThis;
        m_pThis = spThis.get();
    }

private:
    virtual void OnEventFDTrigger() override { (m_pThis->*m_callback)(m_var1, m_var2, m_var3, m_var4); delete this; }

private:
    TheClass*               m_pThis;
    shared_ptr<TheClass>    m_spThis;
    void (TheClass::*m_callback)(VarType1 var1, VarType2 var2, VarType3 var3, VarType4 var4);
    VarType1                m_var1;
    VarType2                m_var2;
    VarType3                m_var3;
    VarType4                m_var4;
};

//
// CMessageDataV5: 带5个模板参数的消息结构
//
template <typename TheClass, typename VarType1, typename VarType2, typename VarType3, typename VarType4, typename VarType5>
class CMessageDataV5 : public CEventFDTrigger
{
public:
    CMessageDataV5(CEventEngine *pEngine, void (TheClass::*callback)(VarType1 var1, VarType2 var2, VarType3 var3, VarType4 var4, VarType5 var5), VarType1 var1, VarType2 var2, VarType3 var3, VarType4 var4, VarType5 var5, TheClass *pThis)
        : CEventFDTrigger(pEngine), m_var1(var1), m_var2(var2), m_var3(var3), m_var4(var4), m_var5(var5)
    {
        m_callback = callback;
        m_pThis = pThis;
    }

    CMessageDataV5(CEventEngine *pEngine, void (TheClass::*callback)(VarType1 var1, VarType2 var2, VarType3 var3, VarType4 var4, VarType5 var5), VarType1 var1, VarType2 var2, VarType3 var3, VarType4 var4, VarType5 var5, shared_ptr<TheClass> spThis)
        : CEventFDTrigger(pEngine), m_var1(var1), m_var2(var2), m_var3(var3), m_var4(var4), m_var5(var5)
    {
        assert(spThis != nullptr);
        m_callback = callback;
        m_spThis = spThis;
        m_pThis = spThis.get();
    }

private:
    virtual void OnEventFDTrigger() override { (m_pThis->*m_callback)(m_var1, m_var2, m_var3, m_var4, m_var5); delete this; }

private:
    TheClass*               m_pThis;
    shared_ptr<TheClass>    m_spThis;
    void (TheClass::*m_callback)(VarType1 var1, VarType2 var2, VarType3 var3, VarType4 var4, VarType5 var5);
    VarType1                m_var1;
    VarType2                m_var2;
    VarType3                m_var3;
    VarType4                m_var4;
    VarType5                m_var5;
};

//
// CMessageMap: 消息映射类，将消息同步到指定的线程执行
//
class CMessageMap
{
public:
    CMessageMap(CEventEngine *pEngine)
    {
        m_pEngine = pEngine;
    }

public:
    //
    // 功能: 无参的消息响应函数，通过裸指针回调
    //
    template <typename TheClass>
    Bool PostMessage(void (TheClass::*callback)(), TheClass *pThis)
    {
        CMessageDataV0<TheClass> *pMsg = new CMessageDataV0<TheClass>(m_pEngine, callback, pThis);
        return pMsg->TriggerReadEvent();
    }

    //
    // 功能: 无参的消息响应函数，通过智能指针回调
    //
    template <typename TheClass>
    Bool PostMessage(void (TheClass::*callback)(), shared_ptr<TheClass> spThis)
    {
        CMessageDataV0<TheClass> *pMsg = new CMessageDataV0<TheClass>(m_pEngine, callback, spThis);
        return pMsg->TriggerReadEvent();
    }

    //
    // 功能: 带1个模板参数的消息响应函数，通过裸指针回调
    //
    template <typename TheClass, typename VarType1>
    Bool PostMessage(void (TheClass::*callback)(VarType1 var1), VarType1 var1, TheClass *pThis)
    {
        CMessageDataV1<TheClass, VarType1> *pMsg = new CMessageDataV1<TheClass, VarType1>(m_pEngine, callback, var1, pThis);
        return pMsg->TriggerReadEvent();
    }

    //
    // 功能: 带1个模板参数的消息响应函数，通过智能指针回调
    //
    template <typename TheClass, typename VarType1>
    Bool PostMessage(void (TheClass::*callback)(VarType1 var1), VarType1 var1, shared_ptr<TheClass> spThis)
    {
        CMessageDataV1<TheClass, VarType1> *pMsg = new CMessageDataV1<TheClass, VarType1>(m_pEngine, callback, var1, spThis);
        return pMsg->TriggerReadEvent();
    }

    //
    // 功能: 带2个模板参数的消息响应函数，通过裸指针回调
    //
    template <typename TheClass, typename VarType1, typename VarType2>
    Bool PostMessage(void (TheClass::*callback)(VarType1 var1, VarType2 var2), VarType1 var1, VarType2 var2, TheClass *pThis)
    {
        CMessageDataV2<TheClass, VarType1, VarType2> *pMsg = new CMessageDataV2<TheClass, VarType1, VarType2>(m_pEngine, callback, var1, var2, pThis);
        return pMsg->TriggerReadEvent();
    }

    //
    // 功能: 带2个模板参数的消息响应函数，通过智能指针回调
    //
    template <typename TheClass, typename VarType1, typename VarType2>
    Bool PostMessage(void (TheClass::*callback)(VarType1 var1, VarType2 var2), VarType1 var1, VarType2 var2, shared_ptr<TheClass> spThis)
    {
        CMessageDataV2<TheClass, VarType1, VarType2> *pMsg = new CMessageDataV2<TheClass, VarType1, VarType2>(m_pEngine, callback, var1, var2, spThis);
        return pMsg->TriggerReadEvent();
    }

    //
    // 功能: 带3个模板参数的消息响应函数，通过裸指针回调
    //
    template <typename TheClass, typename VarType1, typename VarType2, typename VarType3>
    Bool PostMessage(void (TheClass::*callback)(VarType1 var1, VarType2 var2, VarType3 var3), VarType1 var1, VarType2 var2, VarType3 var3, TheClass *pThis)
    {
        CMessageDataV3<TheClass, VarType1, VarType2, VarType3> *pMsg = new CMessageDataV3<TheClass, VarType1, VarType2, VarType3>(m_pEngine, callback, var1, var2, var3, pThis);
        return pMsg->TriggerReadEvent();
    }

    //
    // 功能: 带3个模板参数的消息响应函数，通过智能指针回调
    //
    template <typename TheClass, typename VarType1, typename VarType2, typename VarType3>
    Bool PostMessage(void (TheClass::*callback)(VarType1 var1, VarType2 var2, VarType3 var3), VarType1 var1, VarType2 var2, VarType3 var3, shared_ptr<TheClass> spThis)
    {
        CMessageDataV3<TheClass, VarType1, VarType2, VarType3> *pMsg = new CMessageDataV3<TheClass, VarType1, VarType2, VarType3>(m_pEngine, callback, var1, var2, var3, spThis);
        return pMsg->TriggerReadEvent();
    }

    //
    // 功能: 带4个模板参数的消息响应函数，通过裸指针回调
    //
    template <typename TheClass, typename VarType1, typename VarType2, typename VarType3, typename VarType4>
    Bool PostMessage(void (TheClass::*callback)(VarType1 var1, VarType2 var2, VarType3 var3, VarType4 var4), VarType1 var1, VarType2 var2, VarType3 var3, VarType4 var4, TheClass *pThis)
    {
        CMessageDataV4<TheClass, VarType1, VarType2, VarType3, VarType4> *pMsg = new CMessageDataV4<TheClass, VarType1, VarType2, VarType3, VarType4>(m_pEngine, callback, var1, var2, var3, var4, pThis);
        return pMsg->TriggerReadEvent();
    }

    //
    // 功能: 带4个模板参数的消息响应函数，通过智能指针回调
    //
    template <typename TheClass, typename VarType1, typename VarType2, typename VarType3, typename VarType4>
    Bool PostMessage(void (TheClass::*callback)(VarType1 var1, VarType2 var2, VarType3 var3, VarType4 var4), VarType1 var1, VarType2 var2, VarType3 var3, VarType4 var4, shared_ptr<TheClass> spThis)
    {
        CMessageDataV4<TheClass, VarType1, VarType2, VarType3, VarType4> *pMsg = new CMessageDataV4<TheClass, VarType1, VarType2, VarType3, VarType4>(m_pEngine, callback, var1, var2, var3, var4, spThis);
        return pMsg->TriggerReadEvent();
    }

    //
    // 功能: 带5个模板参数的消息响应函数，通过裸指针回调
    //
    template <typename TheClass, typename VarType1, typename VarType2, typename VarType3, typename VarType4, typename VarType5>
    Bool PostMessage(void (TheClass::*callback)(VarType1 var1, VarType2 var2, VarType3 var3, VarType4 var4, VarType5 var5), VarType1 var1, VarType2 var2, VarType3 var3, VarType4 var4, VarType5 var5, TheClass *pThis)
    {
        CMessageDataV5<TheClass, VarType1, VarType2, VarType3, VarType4, VarType5> *pMsg = new CMessageDataV5<TheClass, VarType1, VarType2, VarType3, VarType4, VarType5>(m_pEngine, callback, var1, var2, var3, var4, var5, pThis);
        return pMsg->TriggerReadEvent();
    }

    //
    // 功能: 带5个模板参数的消息响应函数，通过智能指针回调
    //
    template <typename TheClass, typename VarType1, typename VarType2, typename VarType3, typename VarType4, typename VarType5>
    Bool PostMessage(void (TheClass::*callback)(VarType1 var1, VarType2 var2, VarType3 var3, VarType4 var4, VarType5 var5), VarType1 var1, VarType2 var2, VarType3 var3, VarType4 var4, VarType5 var5, shared_ptr<TheClass> spThis)
    {
        CMessageDataV5<TheClass, VarType1, VarType2, VarType3, VarType4, VarType5> *pMsg = new CMessageDataV5<TheClass, VarType1, VarType2, VarType3, VarType4, VarType5>(m_pEngine, callback, var1, var2, var3, var4, var5, spThis);
        return pMsg->TriggerReadEvent();
    }

private:
    CEventEngine*       m_pEngine;
};
